#include "factoralg.h"
#include "test.h"
#include "stdio.h"

static void TestPrime()
{
   Hinteger number;
   number = 1ul;
   CHECK_TRUE(checkOnePrime(number));

   number = 2ul;
   CHECK_TRUE(checkOnePrime(number));

   number = 3ul;
   CHECK_TRUE(checkOnePrime(number));

   number = 7ul;
   CHECK_TRUE(checkOnePrime(number));

   number = 13ul;
   CHECK_TRUE(checkOnePrime(number));

   number = 127ul;
   CHECK_TRUE(checkOnePrime(number));

   number = 607ul;
   CHECK_TRUE(checkOnePrime(number));

   number = 128ul;
   CHECK_TRUE(!checkOnePrime(number));

   number = 961ul;
   CHECK_TRUE(!checkOnePrime(number));

   number = 3721ul;
   CHECK_TRUE(!checkOnePrime(number));

   //number = "162259276829213363391578010288127";
   CHECK_TRUE(!checkOnePrime(number));
}

static void TestFactor()
{
   Hinteger number = 91ul;
   TFactorList *primes, *base;
   base = primes = createFactorPrimes(number);

   CHECK_EQ(primes->factor.d_str(), "7");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "13");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_TRUE(primes == NULL);

   freeFactorPrimes(base);
}

static void TestFactor_61()
{
   Hinteger number = "61";
   TFactorList *primes, *base;
   base = primes = createFactorPrimes(number);

   CHECK_EQ(primes->factor.d_str(), "61");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_TRUE(primes == NULL);

   freeFactorPrimes(base);
}

static void TestFactor_130352984759372760()
{
   Hinteger number = "130352984759372760";
   TFactorList *primes, *base;
   base = primes = createFactorPrimes(number);

   CHECK_EQ(primes->factor.d_str(), "2");
   CHECK_TRUE(primes->count == 3);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "3");
   CHECK_TRUE(primes->count == 2);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "5");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "7");
   CHECK_TRUE(primes->count == 4);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "11");
   CHECK_TRUE(primes->count == 2);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "17");
   CHECK_TRUE(primes->count == 2);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "19");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "61");
   CHECK_TRUE(primes->count == 3);

   primes = primes->next;
   CHECK_TRUE(primes == NULL);

   freeFactorPrimes(base);
}

static void TestFactor_2ToNminus1Prime()
{
   CHECK_TRUE(isBiToQuMinusOnePrime(2));
   CHECK_TRUE(isBiToQuMinusOnePrime(3));
   CHECK_TRUE(!isBiToQuMinusOnePrime(4));
   CHECK_TRUE(isBiToQuMinusOnePrime(5));
   CHECK_TRUE(!isBiToQuMinusOnePrime(6));
   CHECK_TRUE(isBiToQuMinusOnePrime(7));
   CHECK_TRUE(!isBiToQuMinusOnePrime(8));
   CHECK_TRUE(!isBiToQuMinusOnePrime(9));
   CHECK_TRUE(!isBiToQuMinusOnePrime(10));
   CHECK_TRUE(isBiToQuMinusOnePrime(13));
}

static void TestFactor_2ToNMinus1()
{
   TFactorList *primes, *base;

//  11
// 2  - 1

   base = primes = createBiToQuMinusOnePrimes(11);

   CHECK_EQ(primes->factor.d_str(), "23");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "89");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_TRUE(primes == NULL);

   freeFactorPrimes(base);

//   16
//  2  - 1

   base = primes = createBiToQuMinusOnePrimes(16);

   CHECK_EQ(primes->factor.d_str(), "3");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "5");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "17");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "257");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_TRUE(primes == NULL);

   freeFactorPrimes(base);

//   20
//  2  - 1

   base = primes = createBiToQuMinusOnePrimes(20);

   CHECK_EQ(primes->factor.d_str(), "3");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "5");
   CHECK_TRUE(primes->count == 2);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "11");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "31");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_EQ(primes->factor.d_str(), "41");
   CHECK_TRUE(primes->count == 1);

   primes = primes->next;
   CHECK_TRUE(primes == NULL);

   freeFactorPrimes(base);

}

void TestFactorAlg()
{
   TestPrime();
   TestFactor();
   TestFactor_61();
   TestFactor_130352984759372760();

   TestFactor_2ToNminus1Prime();
   TestFactor_2ToNMinus1();
}
